#ifndef _PROTOCOL_BTYE_H_
#define _PROTOCOL_BTYE_H_

#include <vector>
using std::vector;
#include <string>
using std::string;

#include "sysdef.h"

int sys_trim(const char* inbuf, ushort inlen, char* &start);

enum
{
    BYTE_SIGN_ROOT = 0,
    BYTE_SIGN_NODE
};

class CByteBlock;

class CByteBuffer
{
    CByteBuffer(const CByteBuffer &r);

    CByteBuffer& operator= (const CByteBuffer& r);

public:

    CByteBuffer(const char* ownername = "");

    CByteBuffer(const char* inbuf, ushort inlen, const char* ownername = "");

    virtual ~CByteBuffer(){}

    virtual int ToBlock(CByteBlock* block);
    
    const char* GetOwnerName(){ return m_ownername.c_str(); }

    const char* GetByte() { return &m_data[0]; }
    ushort GetSize() { return m_data.size()-1; }

    bool Read(char* outbuf, ushort outlen);
    bool Write(const char* inbuf, ushort inlen);

    bool Read(uchar& c)     { return Read((char*)&c, sizeof(uchar)); }
    bool Write(uchar c)     { return Write((const char*)&c, sizeof(uchar)); }
    
    bool Read(ushort& size) { return Read((char*)&size, sizeof(ushort)); }
    bool Write(ushort size) { return Write((const char*)&size, sizeof(ushort)); }

private:

    ushort  m_rpos;
    ushort  m_wpos;
    string  m_ownername;
    vector<char> m_data;
};

class CByteBlock;

typedef vector<CByteBlock*>::const_iterator BlockIterator;

class CByteBlock
{
    friend class CByteBuffer;

    template<typename T> friend CByteBlock* AddChild(CByteBlock* block, uchar sign);

    CByteBlock(const CByteBlock &r);

    CByteBlock& operator= (const CByteBlock& r);

protected:

    CByteBlock(uchar sign, CByteBlock* parent);

public:

    CByteBlock(const char* ownername = "");

    virtual ~CByteBlock();

    virtual int ToBuffer(CByteBuffer* buffer);

    uchar GetBlockSign() { return m_blocksign; }
    
    const string& GetBlockName(){ return m_blockname; } 
    
    const string& GetBlockValue(){ return m_blockvalue; }

    const char* GetOwnerName(){ return m_ownername.c_str(); }

    bool IsEmpty();
    
    CByteBlock* GetParent();

    int GetChildCount(uchar sign, const char* name);

    CByteBlock* GetNextChild(uchar index = 1);

    CByteBlock* FindChild(uchar sign, uchar index = 1);

    CByteBlock* FindChild(uchar sign, const char* name, uchar index = 1);
    
    int SetBlockName(string name);

    int SetBlockName(const char* name, ushort namelen);

    int SetBlockValue(string value);
        
    int SetBlockValue(const char* value, ushort valuelen);

protected:

    uchar   m_blocksign;
    string  m_blockname;
    string  m_blockvalue;
    string  m_seperator;
    string  m_ownername;
    CByteBlock* m_parent;
    vector<CByteBlock*> m_children;
};

bool en_byte_node(CByteBlock& root, string name, string value);

bool de_byte_node(CByteBlock& root, string name, string& value, uchar index = 1);

template<typename T> CByteBlock* AddChild(CByteBlock* block, uchar sign)
{
    if(0 == sign) return NULL;

    CByteBlock* child = new T(sign, block);

    if(NULL != child) block->m_children.push_back(child);

    return child;
}

#endif //_PROTOCOL_BTYE_H_
